﻿using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.IO;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.Geometry;


using System.Collections.Generic;
using PlanningGIS.ArcGIS;
using PlanningGIS.Win.Controls;

namespace PlanningGIS.Framework.Controls
{
    ///<summary>
    ///功能：鹰眼功能
    ///作者：：
    ///开发时间：20091028再次扩展功能
    ///</summary>
    public partial class OverViewPanel : UserControl
    {
        /// <summary>
        /// 
        /// </summary>
        IFillShapeElement pFillShapeElement = null;
        /// <summary>
        /// 
        /// </summary>
        IMoveEnvelopeFeedback pFeedback = null;
        /// <summary>
        /// 
        /// </summary>
        OverViewTreeView myform = null;
        /// <summary>
        /// 
        /// </summary>
        IEnvelope m_Envelope = null;
        /// <summary>
        /// 
        /// </summary>
        private IMapControl3 m_MapControl;
        /// <summary>
        /// 
        /// </summary>
        public string zoomscale = "2";
        /// <summary>
        /// 
        /// </summary>
        public string eyetype = "0";
        /// <summary>
        /// 
        /// </summary>
        public string eyepath = "";
        /// <summary>
        /// 
        /// </summary>
        public string eyelyr = "";
        /// <summary>
        /// 
        /// </summary>
        public IMapControl3 MapControl
        {
            get
            {
                return m_MapControl;
            }
            set
            {
                m_MapControl = value;
                if (m_MapControl != null)
                {
                    IMapControlEvents2_Event pEvent = this.m_MapControl as IMapControlEvents2_Event;
                    //pEvent.OnExtentUpdated -= new IMapControlEvents2_OnExtentUpdatedEventHandler(pEvent_OnExtentUpdated);
                    //pEvent.OnExtentUpdated += new IMapControlEvents2_OnExtentUpdatedEventHandler(pEvent_OnExtentUpdated);
                    pEvent.OnMapReplaced -= new IMapControlEvents2_OnMapReplacedEventHandler(pEvent_OnMapReplaced);
                    pEvent.OnMapReplaced += new IMapControlEvents2_OnMapReplacedEventHandler(pEvent_OnMapReplaced);
                    pEvent.OnViewRefreshed -= new IMapControlEvents2_OnViewRefreshedEventHandler(pEvent_OnViewRefreshed);
                    pEvent.OnViewRefreshed += new IMapControlEvents2_OnViewRefreshedEventHandler(pEvent_OnViewRefreshed);
                    pEvent_OnMapReplaced(null);
                }
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="ActiveView"></param>
        /// <param name="viewDrawPhase"></param>
        /// <param name="layerOrElement"></param>
        /// <param name="envelope"></param>
        void pEvent_OnViewRefreshed(object ActiveView, int viewDrawPhase, object layerOrElement, object envelope)
        {
            if (viewDrawPhase == 65535 && m_MapControl != null)
            {
              if (this.Visible == false) return;
                try
                {

                    // GC.Collect();
                    IGraphicsContainer pGra = this.eMapControl.Map as IGraphicsContainer;
                    IActiveView pAv = pGra as IActiveView;

                    //在绘制前，清除EagleMap中的任何图形元素
                    if (pFillShapeElement != null)
                    {
                        pGra.DeleteElement(pFillShapeElement as IElement);
                        GetFillShapElement(this.m_MapControl.ActiveView.Extent as IEnvelope);
                        pGra.AddElement((IElement)pFillShapeElement, 0);
                    }

                    if (eyetype == "0")
                    {
                        //在绘制前，清除EagleMap中的任何图形元素
                        if (pFillShapeElement != null)
                        {
                            pGra.DeleteElement(pFillShapeElement as IElement);
                            GetFillShapElement(this.m_MapControl.ActiveView.Extent as IEnvelope);
                            pGra.AddElement((IElement)pFillShapeElement, 0);
                        }
                    }
                    else
                    {
                        IEnvelope pEnvelope = this.m_MapControl.ActiveView.Extent;// newEnvelope as IEnvelope; 
                        string strRatio = zoomscale;
                        //pEnvelope.Expand(double.Parse(strRatio), double.Parse(strRatio), true);

                        //在绘制前，清除EagleMap中的任何图形元素
                        if (pFillShapeElement != null)
                            pGra.DeleteElement(pFillShapeElement as IElement);
                        GetFillShapElement(pEnvelope);
                        pGra.AddElement((IElement)pFillShapeElement, 0);

                        IEnvelope mEnvelope = this.m_MapControl.ActiveView.Extent as IEnvelope;
                        mEnvelope.Expand(double.Parse(strRatio), double.Parse(strRatio), true);
                        this.eMapControl.Extent = mEnvelope;

                    }
                    pAv.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
                }
                catch
                {

                }
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public OverViewPanel()
        {
            InitializeComponent();
            this.VisibleChanged += new EventHandler(OverViewPanel_VisibleChanged);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void OverViewPanel_VisibleChanged(object sender, EventArgs e)
        {
            if (m_MapControl == null) return;
            if (this.Visible && eMapControl.IsDisposed==false )
            {
                try
                {
                    pEvent_OnViewRefreshed(m_MapControl.ActiveView, 65535, null, m_MapControl.ActiveView.Extent);
                }
                catch (System.Exception)
                {
                }
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="newMap"></param>
        public void pEvent_OnMapReplaced(object newMap)
        {
            OverViewPanelLoad();
            InitMapControl();
        }
        /// <summary>
        /// 
        /// </summary>
        private void InitMapControl()
        {
            GC.Collect();
            try
            {
                IGraphicsContainer pGra = this.eMapControl.Map as IGraphicsContainer;
                IActiveView pAv = pGra as IActiveView;
                //在绘制前，清除EagleMap中的任何图形元素
                pGra.Reset();
                IElement pElement = pGra.Next();
                while (pElement != null)
                {
                    if (pElement == pFillShapeElement)
                    {
                        pGra.DeleteElement(pFillShapeElement as IElement);
                    }
                    pElement = pGra.Next();
                }
                if (eyetype == "0")
                {
                    GetFillShapElement(this.m_MapControl.Extent);
                    pGra.AddElement((IElement)pFillShapeElement, 0);
                }
                else
                {
                    IEnvelope pEnvelope = this.m_MapControl.Extent;//e.newEnvelope as IEnvelope;          
                    GetFillShapElement(pEnvelope);
                    pGra.AddElement((IElement)pFillShapeElement, 0);
                    string strRatio =zoomscale;
                    pEnvelope.Expand(double.Parse(strRatio), double.Parse(strRatio), true);
                    this.eMapControl.Extent = pEnvelope;
                }
                pAv.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
            }
            catch
            {
            }
        }

        #region EMapControl
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void eMapControl1_OnMouseDown(object sender, IMapControlEvents2_OnMouseDownEvent e)
        {
            try
            {
                switch (e.button)
                {
                    case 1:
                        if (eyetype == "0")
                        {
                            eMapControl.MousePointer = esriControlsMousePointer.esriPointerCrosshair;
                            IEnvelope ienvelope = this.eMapControl.TrackRectangle();
                            m_MapControl.Extent = ienvelope;
                        }
                        break;
                    case 2:
                        if (eyetype == "1")
                        {
                            ContextMenuStrip pContextMenu = new ContextMenuStrip();
                            ToolStripMenuItem pItemSelectMxd = new ToolStripMenuItem("选择模板");
                            pItemSelectMxd.Click += new EventHandler(pItemSelectMxd_Click);
                            pContextMenu.Items.Add(pItemSelectMxd);

                            pContextMenu.Show(eMapControl, e.x, e.y);
                        }
                        break;

                    case 4:
                        IPoint ipoint = this.eMapControl.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(e.x, e.y);
                        eMapControl.MousePointer = esriControlsMousePointer.esriPointerPanning;
                        pFeedback = new MoveEnvelopeFeedback();
                        pFeedback.Display = eMapControl.ActiveView.ScreenDisplay;
                        pFeedback.Start(m_MapControl.Extent, ipoint);
                        break;
                }
            }
            catch
            {
                pFeedback = null;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void pItemSelectMxd_Click(object sender, EventArgs e)
        {
            OpenFileDialog dialog = new OpenFileDialog();
            dialog.Filter = "Mxd File|*.mxd";
            DialogResult result = dialog.ShowDialog();
            if (result == DialogResult.OK)
            {
                string fileName = dialog.FileName;

                if (fileName.Contains(Application.StartupPath))
                {
                    fileName = fileName.Substring(Application.StartupPath.Length);
                }
                AppConfig.SystemConfig.鹰眼图.鹰眼模板 = fileName;
                eyepath = fileName;
                pEvent_OnMapReplaced(null);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void eMapControl1_OnMouseMove(object sender, IMapControlEvents2_OnMouseMoveEvent e)
        {
            try
            {
                switch (e.button)
                {
                    case 0:
                        if (eyetype == "0")
                            this.eMapControl.MousePointer = esriControlsMousePointer.esriPointerDefault;
                        break;
                    case 1:
                        if (eyetype == "0")
                            eMapControl.MousePointer = esriControlsMousePointer.esriPointerCrosshair;
                        break;
                    case 4:
                        eMapControl.MousePointer = esriControlsMousePointer.esriPointerPanning;
                        if (pFeedback != null)
                        {
                            IPoint ipoint = eMapControl.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(e.x, e.y);
                            pFeedback.MoveTo(ipoint);
                        }
                        break;
                }
            }
            catch
            {
                pFeedback = null;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void eMapControl1_OnMouseUp(object sender, IMapControlEvents2_OnMouseUpEvent e)
        {
            this.eMapControl.MousePointer = esriControlsMousePointer.esriPointerDefault;
            if ((this.m_MapControl != null) && ((e.button == 4) && (this.pFeedback != null)))
                this.m_MapControl.Extent = this.pFeedback.Stop();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void eMapControl_OnDoubleClick(object sender, IMapControlEvents2_OnDoubleClickEvent e)
        {
            try
            {
                this.Cursor = Cursors.WaitCursor;
                IMap m_Map = null;
                IMapDocument mapDoc = new MapDocument();

                if (eyetype == "0")
                {
                    m_Map = this.m_MapControl.Map;
                    #region
                    this.eMapControl.ClearLayers();
                    if (m_MapControl.LayerCount == 0) return;
                    for (int i = this.m_MapControl.LayerCount - 1; i >= 0; i--)
                    {
                        ILayer pLayer = this.m_MapControl.get_Layer(i);
                        ILayerFile layerFile = new LayerFile(); //创建图层文件实例
                        string path = AppConfig.DataPath + "\\" + Guid.NewGuid() + ".lyr";
                        if (File.Exists(path))
                        {
                            //删除已经存在的文件
                            File.Delete(path);
                        }
                        layerFile.New(path); //创建图层文件

                        layerFile.ReplaceContents(pLayer); //和实际图层相关联
                        layerFile.Save(); //保存图层文件

                        eMapControl.AddLayerFromFile(path);
                        File.Delete(path);
                    }
                    List<IFeatureLayer> featureLayers = MapHelper.GetAllLayer<IFeatureLayer>(this.eMapControl.Map);

                    foreach (IFeatureLayer pFeatureLayer in featureLayers)
                    {
                        if (eyelyr.ToUpper().Contains("[ALL]"))
                        {
                            pFeatureLayer.Visible = true;
                        }
                        else
                        {
                            pFeatureLayer.Visible = (eyelyr.Contains(pFeatureLayer.Name));
                        }
                    }
                    #endregion
                }
                else if (eyetype == "1")
                {
                    if (this.eMapControl.DocumentFilename == null) 
                    {
                        MsgHelper.ShowWarningMsgbox("鹰眼图还未加载模版！");
                        return;
                    }
                    mapDoc.Open(this.eMapControl.DocumentFilename, "");
                    m_Map = mapDoc.get_Map(0);
                }

                m_Envelope = new Envelope() as IEnvelope;
                this.Cursor = Cursors.Default;
                if (m_Map != null)
                {
                    myform = new OverViewTreeView();
                    int intLayerCount = m_Map.LayerCount;

                    for (int i = 0; i < intLayerCount; i++)
                    {
                        ILayer pLayer = m_Map.get_Layer(i);
                        InitTreeView(myform.treeView1.Nodes, pLayer);
                    }
                    myform.treeView1.ExpandAll();
                    myform.SetBuddy(this.eMapControl.Object);

                    if (myform.ShowDialog(this) == DialogResult.OK)
                    {
                        //added by sheng  同步修改配置文件
                        string temp = "";

                        GetVisibleLyrs(this.eMapControl.Map, ref temp);

                        if (temp != "")
                        {
                            temp = temp.Substring(0, temp.Length - 1);
                        }
                        AppConfig.SystemConfig.鹰眼图.鹰眼图层 = temp;
                        if (eyetype == "0")
                        {
                            eyelyr = temp;                            
                        }
                        else
                        {
                            mapDoc.ReplaceContents(this.eMapControl.Map as IMxdContents);
                            IGraphicsContainer pGra = this.eMapControl.Map as IGraphicsContainer;
                            IActiveView pAv = pGra as IActiveView;
                            pGra.DeleteAllElements();   //为了保存的时候，不要把红框也保存进去
                            mapDoc.Save(mapDoc.UsesRelativePaths, false);
                            mapDoc.Close();
                            this.eMapControl.Refresh();//为了加红框
                        }
                    }
                }
                //if (AppConfig.SystemConfig.鹰眼图.鹰眼类型.ToString() == "1")
                {
                    this.eMapControl.Extent = m_Envelope;
                }
                InitMapControl();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                this.Cursor = Cursors.Default;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="pMap"></param>
        /// <param name="names"></param>
        private void GetVisibleLyrs(IMap pMap, ref string names)
        {
            if (pMap.LayerCount == 0) return;

            for (int i = 0; i < pMap.LayerCount; i++)
            {
                ILayer pLayer = pMap.get_Layer(i);
                GetVisibleLyrs(pMap, pLayer, ref names);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="pMap"></param>
        /// <param name="pLayer"></param>
        /// <param name="names"></param>
        private void GetVisibleLyrs(IMap pMap, ILayer pLayer, ref string names)
        {
            if (pLayer.Visible)
            {
                if ((pLayer.MaximumScale < pMap.MapScale && pLayer.MinimumScale > pMap.MapScale) ||
                    (pLayer.MaximumScale < pMap.MapScale && pLayer.MinimumScale == 0) ||
                    (pLayer.MaximumScale == 0 && pLayer.MinimumScale > pMap.MapScale) ||
                    (pLayer.MaximumScale == 0 && pLayer.MinimumScale == 0))
                {
                    if (pLayer is ICompositeLayer)
                    {
                        ICompositeLayer pCompositeLyr = pLayer as ICompositeLayer;
                        for (int i = 0; i < pCompositeLyr.Count; i++)
                        {
                            ILayer pLyr2 = pCompositeLyr.get_Layer(i);
                            GetVisibleLyrs(pMap, pLyr2, ref names);
                        }
                    }
                    else
                    {
                        names = names + pLayer.Name + ",";
                    }
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="node"></param>
        private void AddLayer2EgleMap(TreeNode node)
        {
            //ym 20090708 update 
            if (node.Checked)
            {
                ILayer pLayer = node.Tag as ILayer;
                try
                {
                    pLayer.Visible = true;

                    if (node.Nodes.Count > 0)
                    {
                        for (int i = 0; i < node.Nodes.Count; i++)
                        {
                            AddLayer2EgleMap(node.Nodes[i]);
                        }
                    }
                    else
                    {
                        //this.eMapControl.AddLayer(pLayer);
                        //m_Envelope.Union(pLayer.AreaOfInterest);
                    }
                }
                catch
                {
                }
                //this.eMapControl.AddLayer(pLayer);
            }
            else
            {
                ILayer pLayer = node.Tag as ILayer;
                if (node.Nodes.Count > 0)
                {
                    pLayer.Visible = true;
                    for (int i = 0; i < node.Nodes.Count; i++)
                    {
                        AddLayer2EgleMap(node.Nodes[i]);
                    }
                }
                else
                {
                    pLayer.Visible = false;
                }
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="nodes"></param>
        /// <param name="pLayer"></param>
        private void InitTreeView(TreeNodeCollection nodes, ILayer pLayer)
        {
            TreeNode node = new TreeNode(pLayer.Name);
            node.Tag = pLayer;
            nodes.Add(node);
            ILayer mLayer = null;
            bool flag = false; ;
            for (int j = 0; j < this.eMapControl.LayerCount; j++)
            {
                mLayer = this.eMapControl.get_Layer(j);
                if (mLayer != null && mLayer.Visible)
                {
                    if (mLayer.Name == pLayer.Name)
                    {
                        myform.treeView1.SelectedNode = node;
                        flag = true;
                    }
                }
            }
            node.Checked = flag;
            if (pLayer is IGroupLayer)
            {
                ICompositeLayer pCompositeLayer = pLayer as ICompositeLayer;
                for (int i = 0; i < pCompositeLayer.Count; i++)
                    InitTreeView(node.Nodes, pCompositeLayer.get_Layer(i));
            }
        }
        
        /// <summary>
        /// 
        /// </summary>
        /// <param name="pEnv"></param>
        private void GetFillShapElement(IEnvelope pEnv)
        {
            IRectangleElement pRectangleEle = new RectangleElement() as IRectangleElement;
            IElement pEle = pRectangleEle as IElement;
            pEle.Geometry = pEnv;
            //设置鹰眼图中的红线框
            IRgbColor pColor = new RgbColor();
            pColor.Red = 255;
            pColor.Green = 0;
            pColor.Blue = 0;
            pColor.Transparency = 255;
            //产生一个线符号对象
            ILineSymbol pOutline = new SimpleLineSymbol();
            pOutline.Width = 2;
            pOutline.Color = pColor;
            //设置颜色属性
            pColor = new RgbColor();
            pColor.Red = 255;
            pColor.Green = 0;
            pColor.Blue = 0;
            pColor.Transparency = 0;
            ILineFillSymbol pLineFillSymbol = new LineFillSymbol();
            pLineFillSymbol.Outline = pOutline;
            pLineFillSymbol.Angle = 45;
            pLineFillSymbol.Color = pColor;
            pLineFillSymbol.Separation = 4;

            pFillShapeElement = pEle as IFillShapeElement;
            pFillShapeElement.Symbol = (IFillSymbol)pLineFillSymbol;
        }
        
        /// <summary>
        /// 初始化鹰眼图层
        /// </summary>
        /// <param name="pLayer"></param>
        private void InitLayer(ILayer pLayer)
        {
            string strLayer = eyelyr;
            string[] strLayers = strLayer.Split(',');
            for (int j = 0; j < strLayers.Length; j++)
            {
                if (pLayer.Name.ToString() == strLayers[j].ToString())
                {
                    this.eMapControl.AddLayer(pLayer);
                }
                else if (pLayer is IGroupLayer)
                {
                    ICompositeLayer pCompositeLayer = pLayer as ICompositeLayer;
                    for (int i = 0; i < pCompositeLayer.Count; i++)
                    {
                        InitLayer(pCompositeLayer.get_Layer(i));
                    }
                }
            }
        }
        #endregion
        /// <summary>
        /// 
        /// </summary>
        private void OverViewPanelLoad()
        {
            try
            {
                eyetype = AppConfig.SystemConfig.鹰眼图.鹰眼类型.ToString();
                eyelyr = AppConfig.SystemConfig.鹰眼图.鹰眼图层.ToString();
                eyepath = AppConfig.SystemConfig.鹰眼图.鹰眼模板.ToString();

                if (eyetype == "1")
                {
                    this.Cursor = Cursors.WaitCursor;
                    string filePath = eyepath;
                    string docName = "";
                    if (File.Exists(filePath))
                        docName = filePath;
                    
                    else if (File.Exists(AppConfig.SysFolder + filePath))
                        docName = AppConfig.SysFolder + filePath;
                    if (docName == "")
                    {
                        //MsgHelper.ShowInfomationMsgbox("找不到鹰眼图数据源，请重新配置！");
                        return;
                    }
                    this.eMapControl.LoadMxFile(docName);
                }
                else if (eyetype== "0")
                {
                    this.eMapControl.ClearLayers();
                    if (m_MapControl.LayerCount == 0) return;
                    for (int i = this.m_MapControl.LayerCount-1; i >=0; i--)
                    {
                        ILayer pLayer = this.m_MapControl.get_Layer(i);
                        ILayerFile layerFile = new LayerFile(); //创建图层文件实例

                        //modified by sheng at 2013-02-25 因为有时候图层名称中含有英文冒号（:）等不能作为文件名的字符，所以会导致创建lyr文件失败，这里直接用一个随机名称
                        //string path = Application.StartupPath +
                        //    (System.Configuration.ConfigurationManager.AppSettings.Get("Folder") == null || System.Configuration.ConfigurationManager.AppSettings.Get("Folder").Trim() == "" ? "" : ("\\" + System.Configuration.ConfigurationManager.AppSettings.Get("Folder"))) +
                        //    "\\Data\\" + Guid.NewGuid() + ".lyr";
                        string path = AppConfig.DataPath + "\\" + Guid.NewGuid() + ".lyr";

                        if (File.Exists(path))
                        {
                            //删除已经存在的文件
                            File.Delete(path);
                        }
                        layerFile.New(path); //创建图层文件
                        
                        layerFile.ReplaceContents(pLayer); //和实际图层相关联
                        layerFile.Save(); //保存图层文件

                        eMapControl.AddLayerFromFile(path);

                        File.Delete(path);

                        //eMapControl.AddLayer(this.m_MapControl.get_Layer(i));
                        //InitLayer(this.m_MapControl.get_Layer(i));
                    }
                    List<IFeatureLayer> featureLayers = MapHelper.GetAllLayer<IFeatureLayer>(this.eMapControl.Map);
                   
                    foreach (IFeatureLayer pFeatureLayer in featureLayers)
                    {
                        if (eyelyr.ToUpper().Contains("[ALL]"))
                        {
                            pFeatureLayer.Visible = true;
                        }
                        else
                        {
                            pFeatureLayer.Visible = (eyelyr.Contains(pFeatureLayer.Name));
                        }
                    }

                    this.eMapControl.Extent = m_MapControl.FullExtent;
                    
                }
                this.eMapControl.Refresh();
            }
            catch (Exception ex)
            {
                MsgHelper.ShowErrorMsgbox(ex.Message);
            }
            finally
            {
                this.Cursor = Cursors.Default;
            }
        }
    }
}